<template>
  <div class="app-container">
    <el-row :gutter="20">
      <splitpanes class="default-theme">
        <!-- 结构树 -->
        <pane size="25">
          <div class="panel-container">
            <div class="panel-header">结构列表</div>
            <div class="search-box">
              <el-input
                v-model="structName"
                placeholder="请输入结构名称"
                clearable
                size="small"
                prefix-icon="el-icon-search" />
            </div>
            <div class="panel-body">
              <el-tree
                :data="structOptions"
                :props="defaultProps"
                :expand-on-click-node="false"
                :filter-node-method="filterStructNode"
                ref="structTree"
                node-key="id"
                default-expand-all
                highlight-current
                @node-click="handleStructNodeClick">
                <span class="tree-node-name" slot-scope="{ node, data }">
                  <i :class="data.isdir === 'Y' ? 'el-icon-folder' : 'el-icon-document'" class="node-icon"></i>
                  {{ node.label }}
                </span>
              </el-tree>
            </div>
          </div>
        </pane>

        <!-- 需求和技术指标区域 -->
        <pane size="75">
          <el-row :gutter="20">
            <!-- 需求列表 -->
            <el-col :span="12">
              <div class="panel-container">
                <div class="panel-header">需求列表</div>
                <div class="search-box">
                  <el-input
                    v-model="demandSearchKey"
                    placeholder="请输入需求名称"
                    clearable
                    size="small"
                    prefix-icon="el-icon-search" />
                </div>
                <div class="panel-body">
                  <el-empty v-if="!currentStruct" description="请先选择左侧结构"></el-empty>
                  <el-table
                    ref="demandTable"
                    v-else
                    :data="filteredDemandList"
                    border
                    v-loading="demandLoading"
                    @selection-change="handleDemandSelectionChange"
                    @row-click="handleDemandRowClick"
                    height="calc(100vh - 250px)">
                    <el-table-column
                      type="selection"
                      width="55"
                      :selectable="isDemandSelectable"
                      :reserve-selection="false">
                      <template slot="header" slot-scope="scope">
                        <!-- Empty header to remove the select all checkbox -->
                      </template>
                      <template slot-scope="scope">
                        <el-tooltip
                          v-if="scope.row.isMapped"
                          content="该需求已配置直接映射关系"
                          placement="top"
                          effect="light"
                          popper-class="mapped-tooltip">
                          <span class="checkbox-wrapper">
                            <el-checkbox disabled></el-checkbox>
                          </span>
                        </el-tooltip>
                        <el-tooltip
                          v-else-if="!isDemandSelectable(scope.row)"
                          :content="getDemandDisabledReason(scope.row)"
                          placement="top"
                          effect="light"
                          popper-class="type-mismatch-tooltip">
                          <span class="checkbox-wrapper">
                            <el-checkbox disabled></el-checkbox>
                          </span>
                        </el-tooltip>
                        <el-checkbox
                          v-else
                          v-model="scope.row.checked"
                          @change="(val) => handleCheckboxChange(val, scope.row, scope.$index)">
                        </el-checkbox>
                      </template>
                    </el-table-column>
                    <el-table-column prop="name" label="需求名称" min-width="200" show-overflow-tooltip></el-table-column>
                    <el-table-column label="需求类型" width="100">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tag size="mini" type="success">文本</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'num'">
                          <el-tag size="mini" type="primary">数字</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tag size="mini" type="warning">范围</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tag size="mini" type="info">选项</el-tag>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="需求值" min-width="150">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tooltip placement="top"
                                     :content="scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '暂无内容'"
                                     :disabled="!scope.row.values || !scope.row.values[0]"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="text-value">{{ scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '-' }}</span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tooltip placement="top"
                                     :content="getOptionsTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-collection-tag"></i> {{ getOptionsCount(scope.row) }}个选项
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tooltip placement="top"
                                     :content="getRangeTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-data-line"></i> {{ getRangeCount(scope.row) }}个范围
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else>
                          <div class="value-wrapper">
                            <span class="empty-value">-</span>
                          </div>
                        </template>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </el-col>

            <!-- 技术指标列表 -->
            <el-col :span="12">
              <div class="panel-container">
                <div class="panel-header">技术指标列表</div>
                <div class="search-box">
                  <el-input
                    v-model="indSearchKey"
                    placeholder="请输入技术指标名称"
                    clearable
                    size="small"
                    prefix-icon="el-icon-search" />
                </div>
                <div class="panel-body">
                  <el-empty v-if="!currentStruct" description="请先选择左侧结构"></el-empty>
                  <el-table
                    ref="indTable"
                    v-else
                    :data="filteredIndList"
                    border
                    v-loading="indLoading"
                    @selection-change="handleIndSelectionChange"
                    @row-click="handleIndRowClick"
                    height="calc(100vh - 250px)">
                    <el-table-column
                      type="selection"
                      width="55"
                      :selectable="isIndicatorSelectable"
                      :reserve-selection="false">
                      <template slot="header" slot-scope="scope">
                        <!-- Empty header to remove the select all checkbox -->
                      </template>
                      <template slot-scope="scope">
                        <el-tooltip
                          v-if="scope.row.isMapped"
                          content="该指标已配置直接映射关系"
                          placement="top"
                          effect="light"
                          popper-class="mapped-tooltip">
                          <span class="checkbox-wrapper">
                            <el-checkbox disabled></el-checkbox>
                          </span>
                        </el-tooltip>
                        <el-tooltip
                          v-else-if="scope.row.type === 'num' && functionMappedIndicators[scope.row.iid || scope.row.id]"
                          content="该指标已配置函数映射关系"
                          placement="top"
                          effect="light"
                          popper-class="mapped-tooltip">
                          <span class="checkbox-wrapper">
                            <el-checkbox disabled></el-checkbox>
                          </span>
                        </el-tooltip>
                        <el-tooltip
                          v-else-if="!isIndicatorSelectable(scope.row)"
                          :content="getIndicatorDisabledReason(scope.row)"
                          placement="top"
                          effect="light"
                          popper-class="type-mismatch-tooltip">
                          <span class="checkbox-wrapper">
                            <el-checkbox disabled></el-checkbox>
                          </span>
                        </el-tooltip>
                        <el-checkbox
                          v-else
                          v-model="scope.row.checked"
                          @change="(val) => handleIndCheckboxChange(val, scope.row, scope.$index)">
                        </el-checkbox>
                      </template>
                    </el-table-column>
                    <el-table-column
                      prop="name"
                      label="指标名称"
                      min-width="200"
                      show-overflow-tooltip
                      :class-name="row => getRowClassName(row)">
                    </el-table-column>
                    <el-table-column label="指标类型" width="100">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tag size="mini" type="success">文本</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'num'">
                          <el-tag size="mini" type="primary">数字</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tag size="mini" type="warning">范围</el-tag>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tag size="mini" type="info">选项</el-tag>
                        </template>
                      </template>
                    </el-table-column>
                    <el-table-column label="指标值" min-width="150">
                      <template slot-scope="scope">
                        <template v-if="scope.row.type === 'text'">
                          <el-tooltip placement="top"
                                     :content="scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '暂无内容'"
                                     :disabled="!scope.row.values || !scope.row.values[0]"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="text-value">{{ scope.row.values && scope.row.values[0] ? scope.row.values[0].value : '-' }}</span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'option'">
                          <el-tooltip placement="top"
                                     :content="getOptionsTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-collection-tag"></i> {{ getOptionsCount(scope.row) }}个选项
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else-if="scope.row.type === 'range'">
                          <el-tooltip placement="top"
                                     :content="getRangeTooltip(scope.row)"
                                     :disabled="!scope.row.values || scope.row.values.length === 0"
                                     popper-class="content-tooltip">
                            <div class="value-wrapper">
                              <span class="count-value">
                                <i class="el-icon-data-line"></i> {{ getRangeCount(scope.row) }}个范围
                              </span>
                            </div>
                          </el-tooltip>
                        </template>
                        <template v-else>
                          <div class="value-wrapper">
                            <span class="empty-value">-</span>
                          </div>
                        </template>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </el-col>
          </el-row>

          <!-- 映射按钮区域 - 只保留一个统一的按钮 -->
          <div class="mapping-actions">
            <el-button
              type="primary"
              class="mapping-btn"
              icon="el-icon-connection"
              :disabled="!canConfigureMapping"
              @click="handleAddMapping">
              配置映射关系
            </el-button>
          </div>
          
          <!-- 函数映射对话框 -->
          <el-dialog
            title="配置函数映射"
            :visible.sync="functionDialog.visible"
            width="650px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            append-to-body
          >
            <div v-loading="functionDialog.loading">
              <el-form :model="functionForm" ref="functionForm" label-width="100px">
                <!-- 自变量列表 -->
                <el-form-item label="自变量" required>
                  <el-table
                    :data="selectedDemands"
                    border
                    size="small"
                    style="width: 100%"
                  >
                    <el-table-column type="index" width="50" label="#" />
                    <el-table-column prop="name" label="需求名称" />
                    <el-table-column prop="varName" label="变量名" width="100">
                      <template slot-scope="scope">
                        <el-input 
                          v-model="scope.row.varName" 
                          size="mini" 
                          placeholder="变量名" 
                          required 
                          :rules="[{ required: true, message: '变量名不能为空', trigger: 'blur' }]" />
                      </template>
                    </el-table-column>
                  </el-table>
                </el-form-item>

                <!-- 因变量 -->
                <el-form-item label="因变量" required>
                  <el-tag type="success" v-if="selectedInds.length > 0">
                    {{ selectedInds[0].name }}
                  </el-tag>
                  <span v-else class="text-muted">请选择一个指标</span>
                </el-form-item>

                <!-- 公式 -->
                <el-form-item label="公式" prop="formula" required>
                  <el-input 
                    v-model="functionForm.formula" 
                    type="textarea" 
                    rows="3"
                    placeholder="请输入计算公式，例如: x1 + x2 * 2"
                  ></el-input>
                  <div class="formula-tips">
                    <p>
                      <b>提示:</b> 使用变量名和数学运算符构建公式: +, -, *, /, ()
                    </p>
                    <p>可用函数: sqrt(), pow(), sin(), cos(), max(), min()等</p>
                  </div>
                </el-form-item>

                <!-- 单位 -->
                <el-form-item label="单位" prop="unit">
                  <el-input v-model="functionForm.unit" placeholder="请输入单位"></el-input>
                </el-form-item>

                <!-- 公式测试 -->
                <el-collapse v-model="functionForm.testActive">
                  <el-collapse-item title="公式测试" name="test">
                    <div v-if="selectedDemands.length > 0">
                      <div v-for="(demand, index) in selectedDemands" :key="demand.did" class="mb-2">
                        <el-form-item :label="demand.varName || '变量' + (index + 1)">
                          <el-input-number 
                            v-model="demand.testValue" 
                            :placeholder="`请输入${demand.varName || '变量' + (index + 1)}的值`"
                            size="small"
                            style="width: 180px"
                          ></el-input-number>
                        </el-form-item>
                      </div>
                      
                      <el-button type="primary" size="small" @click="testFormula" class="mt-2">
                        计算结果
                      </el-button>
                      
                      <div v-if="functionForm.testResult !== null" class="mt-3">
                        <el-alert
                          title="计算结果"
                          type="success"
                          :description="functionForm.testResult + (functionForm.unit ? ' ' + functionForm.unit : '')"
                          show-icon
                        ></el-alert>
                      </div>
                    </div>
                    <div v-else>
                      <el-alert
                        title="请先选择需求作为自变量"
                        type="info"
                        show-icon
                      ></el-alert>
                    </div>
                  </el-collapse-item>
                </el-collapse>
              </el-form>
            </div>
            <div slot="footer" class="dialog-footer">
              <el-button @click="functionDialog.visible = false">取 消</el-button>
              <el-button type="primary" @click="saveFunctionMapping" :loading="functionDialog.loading">
                保 存
              </el-button>
            </div>
          </el-dialog>
        </pane>
      </splitpanes>
    </el-row>

    <!-- 映射配置对话框 -->
    <el-dialog
      :title="mappingDialog.title"
      :visible.sync="mappingDialog.visible"
      width="900px"
      :close-on-click-modal="false"
      class="mapping-dialog"
      @close="cancelMapping"
      @open="handleMappingDialogOpen">
      <div class="mapping-dialog-content">
        <!-- 直接映射配置 -->
        <template v-if="isDirectMapping">
          <div class="mapping-header">
            <i class="el-icon-connection dialog-icon"></i>
            <span class="mapping-subtitle">您正在配置直接映射关系，将建立文本类型需求与技术指标之间的一对一关联。</span>
          </div>

          <el-row :gutter="24">
            <el-col :span="12">
              <div class="mapping-section direct-mapping-section">
                <div class="section-title">
                  <i class="el-icon-document-checked"></i>
                  <span>已选需求</span>
                  <el-tag type="primary" size="mini" class="count-tag">{{ selectedDemands.length }}</el-tag>
                </div>
                <div class="section-content">
                  <el-scrollbar style="height: 220px">
                    <div class="mapping-items">
                      <div
                        v-for="(demand, index) in selectedDemands"
                        :key="'demand-' + demand.id"
                        class="mapping-item">
                        <el-tag
                          class="mapping-tag"
                          effect="plain"
                          type="primary">
                          <i class="el-icon-document"></i>
                          <span class="item-name">{{ demand.name }}</span>
                          <el-tag class="type-tag" size="mini" type="success">文本</el-tag>
                        </el-tag>
                      </div>
                    </div>
                  </el-scrollbar>
                </div>
              </div>
            </el-col>
            <el-col :span="12">
              <div class="mapping-section direct-mapping-section">
                <div class="section-title">
                  <i class="el-icon-data-analysis"></i>
                  <span>已选技术指标</span>
                  <el-tag type="success" size="mini" class="count-tag">{{ selectedInds.length }}</el-tag>
                </div>
                <div class="section-content">
                  <el-scrollbar style="height: 220px">
                    <div class="mapping-items">
                      <div
                        v-for="(ind, index) in selectedInds"
                        :key="'ind-' + ind.id"
                        class="mapping-item">
                        <el-tag
                          class="mapping-tag"
                          effect="plain"
                          type="success">
                          <i class="el-icon-data-line"></i>
                          <span class="item-name">{{ ind.name }}</span>
                          <el-tag class="type-tag" size="mini" type="primary">文本</el-tag>
                        </el-tag>
                      </div>
                    </div>
                  </el-scrollbar>
                </div>
              </div>
            </el-col>
          </el-row>

          <div class="mapping-summary">
            <div class="summary-title">
              <i class="el-icon-info"></i>
              <span>映射预览</span>
            </div>
            <div class="summary-content">
              <p>将创建 <b>{{ selectedDemands.length * selectedInds.length }}</b> 条直接映射关系</p>
              <div class="mapping-preview">
                <div class="mapping-preview-left">
                  <div class="preview-demand-count">{{ selectedDemands.length }}</div>
                  <div class="preview-text">需求</div>
                </div>
                <div class="mapping-preview-arrow">
                  <i class="el-icon-right"></i>
                </div>
                <div class="mapping-preview-right">
                  <div class="preview-ind-count">{{ selectedInds.length }}</div>
                  <div class="preview-text">技术指标</div>
                </div>
              </div>
            </div>
          </div>
        </template>

        <!-- 选项映射配置 -->
        <template v-else-if="isOptionMapping">
          <div class="mapping-header">
            <i class="el-icon-share dialog-icon"></i>
            <span class="mapping-subtitle">您正在配置选项映射关系，请为需求选项和技术指标选项建立一对一的映射。</span>
          </div>

          <div class="option-mapping-container">
            <div class="mapping-instructions">
              <i class="el-icon-info instruction-icon"></i>
              <span>从左右两侧表格中各选择一个选项，然后点击"添加映射"按钮建立映射关系。</span>
            </div>

            <el-row :gutter="20" class="option-mapping-row">
              <el-col :span="10">
                <div class="mapping-section">
                  <div class="section-title option-section-title">
                    <i class="el-icon-collection-tag"></i>
                    <span>需求选项</span>
                    <el-tag size="mini" type="primary" class="source-tag">{{ selectedDemands[0] ? selectedDemands[0].name : '' }}</el-tag>
                  </div>
                  <el-table
                    ref="demandOptionTable"
                    :data="demandOptions"
                    border
                    style="width: 100%"
                    highlight-current-row
                    :row-class-name="getDemandOptionRowClass"
                    @row-click="handleDemandOptionRowClick">
                    <el-table-column
                      prop="value"
                      label="需求选项值">
                    </el-table-column>
                  </el-table>
                </div>
              </el-col>

              <el-col :span="4" class="mapping-action-col">
                <div class="mapping-action-wrapper">
                  <div class="selected-option-container">
                    <div class="selected-option-display">
                      <div class="selected-option selected-demand-option" :class="{'has-selection': currentDemandOption}">
                        <template v-if="currentDemandOption">
                          <i class="el-icon-collection-tag option-icon"></i>
                          <span>{{ currentDemandOption.value }}</span>
                        </template>
                        <template v-else>
                          <span class="placeholder">请选择需求选项</span>
                        </template>
                      </div>

                      <div class="map-direction">
                        <i class="el-icon-arrow-right"></i>
                      </div>

                      <div class="selected-option selected-indicator-option" :class="{'has-selection': currentIndicatorOption}">
                        <template v-if="currentIndicatorOption">
                          <i class="el-icon-collection-tag option-icon"></i>
                          <span>{{ currentIndicatorOption.value }}</span>
                        </template>
                        <template v-else>
                          <span class="placeholder">请选择指标选项</span>
                        </template>
                      </div>
                    </div>
                  </div>

                  <el-button
                    type="primary"
                    size="small"
                    icon="el-icon-connection"
                    class="add-mapping-btn"
                    :disabled="!currentDemandOption || !currentIndicatorOption"
                    :loading="addMappingLoading"
                    @click="addOneToOneMapping">
                    添加映射
                  </el-button>
                </div>
              </el-col>

              <el-col :span="10">
                <div class="mapping-section">
                  <div class="section-title option-section-title">
                    <i class="el-icon-collection-tag"></i>
                    <span>技术指标选项</span>
                    <el-tag size="mini" type="success" class="source-tag">{{ selectedInds[0] ? selectedInds[0].name : '' }}</el-tag>
                  </div>
                  <el-table
                    ref="indicatorOptionTable"
                    :data="indicatorOptions"
                    border
                    highlight-current-row
                    size="small"
                    v-loading="loadingIndicatorOptions"
                    height="240px"
                    class="option-table"
                    @current-change="handleIndicatorOptionSelect">
                    <el-table-column prop="value" label="选项值" min-width="180">
                      <template slot-scope="scope">
                        <div class="option-cell">
                          <span class="option-value">{{ scope.row.value }}</span>
                        </div>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </el-col>
            </el-row>

            <!-- 已有映射关系展示 - 确保这部分代码位置正确 -->
            <div class="existing-mappings-container">
              <div class="section-header">
                <span class="section-title">已有映射关系</span>
                <el-tag v-if="existingMappings.length > 0" type="success" size="small">{{ existingMappings.length }} 条</el-tag>
              </div>
              
              <!-- 有数据时显示映射表 -->
              <div v-if="existingMappings && existingMappings.length > 0">
                <el-table
                  :data="existingMappings"
                  border
                  style="width: 100%; margin-top: 15px;"
                  class="existing-mappings-table">
                  <el-table-column label="需求选项值" min-width="200">
                    <template slot-scope="scope">
                      <div class="option-value-cell demand-option">
                        <span class="option-text">{{ scope.row.demandOptionValue }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  
                  <el-table-column width="120" align="center">
                    <template>
                      <div class="mapping-arrow-container">
                        <div class="mapping-line"></div>
                        <div class="mapping-arrow-wrapper">
                          <i class="el-icon-right mapping-arrow-icon"></i>
                        </div>
                      </div>
                    </template>
                  </el-table-column>
                  
                  <el-table-column label="技术指标选项值" min-width="200">
                    <template slot-scope="scope">
                      <div class="option-value-cell indicator-option">
                        <span class="option-text">{{ scope.row.indicatorOptionValue }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  
                  <el-table-column label="操作" width="100" align="center">
                    <template slot-scope="scope">
                      <el-button
                        type="text"
                        class="delete-btn"
                        @click="removeMapping(scope.row.id)">
                        <i class="el-icon-delete"></i> 删除映射
                      </el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
              
              <!-- 无数据展示 -->
              <el-empty v-else description="暂无映射记录"></el-empty>
            </div>
          </div>
        </template>

        <!-- 默认空白内容 -->
        <template v-else>
          <el-empty description="请选择有效的需求和技术指标"></el-empty>
        </template>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelMapping" size="medium">关 闭</el-button>
        <el-button
          v-if="isDirectMapping"
          type="primary"
          @click="confirmMapping"
          :loading="mappingDialog.loading"
          size="medium">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
import { listStruct } from "@/api/data/struct";
import { getStructDemandByStructId } from "@/api/data/struct_demand";
import { getStructIndByStructId } from "@/api/data/struct_indicator";
import { listInd } from "@/api/data/indicator";
import { listDemand } from "@/api/data/demand";
import { addDirectMapping, getDirectMappingBySid, checkDemandMapped, checkIndicatorMapped } from "@/api/data/direct_mapping";
import {
  getOptionOrRangeDemands,
  getOptionIndicators,
  getDemandOptions,
  getIndicatorOptions,
  batchAddKnowledgeMapping,
  delKnowledgeMapping,
  addKnowledgeMapping,
  getKnowledgeMappingsByDemandAndIndicator,
  getKnowledgeMappingsByStructAndDemandAndIndicator
} from "@/api/data/knowledge_mapping";
import { 
  addFunctionMapping,
  testFormula, 
  checkMappingExists,
  getFunctionMappingBySdidAndSiid,
  getFunctionMappingBySid,
  checkDemandMapped as checkFunctionDemandMapped,
  checkIndicatorMapped as checkFunctionIndicatorMapped
} from "@/api/data/function_mapping";

export default {
  name: "Mapping",
  components: { Treeselect, Splitpanes, Pane },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 结构树相关
      structName: undefined,
      structOptions: [],
      defaultProps: {
        children: "children",
        label: "name"
      },

      // 需求列表相关
      demandSearchKey: '',
      demandList: [],
      selectedDemands: [],

      // 技术指标列表相关
      indSearchKey: '',
      indList: [],
      selectedInds: [],

      // 当前选中的结构节点
      currentStruct: null,
      // 技术指标树选项
      techOptions: undefined,
      // 需求和技术指标的映射列表
      mappingList: [],
      // 当前选中的需求节点
      currentRequirement: null,
      // 当前选中的技术指标节点
      currentTechIndicator: null,
      // 多选选中数据
      multipleSelection: [],
      // 映射类型列表
      mappingTypes: ['直接映射', '条件映射', '函数映射'],
      // 需求加载状态
      demandLoading: true,
      // 技术指标加载状态
      indLoading: true,
      // 映射加载状态
      mappingLoading: false,
      // 添加对话框相关数据
      mappingDialog: {
        visible: false,
        title: '配置映射关系',
        loading: false
      },
      // 映射状态跟踪
      mappedDemands: {},
      mappedIndicators: {},
      // 添加新的数据属性
      demandOptions: [],
      indicatorOptions: [],
      currentDemandOption: null,  // 当前选中的需求选项
      currentIndicatorOption: null,  // 当前选中的指标选项
      loadingDemandOptions: false,
      loadingIndicatorOptions: false,
      knowledgeMappings: [],
      optionMappingsTemp: [],
      addMappingLoading: false,
      optionMappingLoading: false,
      existingMappings: [],
      existingMappingIds: {},
      mappedDemandOptions: {}, // 用于跟踪已映射的需求选项ID
      
      // 函数映射对话框
      functionDialog: {
        visible: false,
        loading: false
      },
      
      // 函数配置表单
      functionForm: {
        id: null,
        formula: '',
        unit: '',
        testActive: [],
        testResult: null
      },
      
      // 保存已配置的映射关系 
      configuredMappings: [], // 存储已配置的映射信息
      functionMappings: [],
      functionMappedDemands: {},
      functionMappedIndicators: {},
    };
  },
  computed: {
    filteredDemandList() {
      if (!this.demandSearchKey) return this.demandList;
      return this.demandList.filter(item =>
        item.name.toLowerCase().includes(this.demandSearchKey.toLowerCase())
      );
    },
    filteredIndList() {
      if (!this.indSearchKey) return this.indList;
      return this.indList.filter(item =>
        item.indicatorName.toLowerCase().includes(this.indSearchKey.toLowerCase())
      );
    },
    getRequirementTextValue() {
      if (!this.currentRequirement.values || !this.currentRequirement.values.length) {
        return '-';
      }
      return this.currentRequirement.values[0].value || '-';
    },
    getTechIndicatorTextValue() {
      if (!this.currentTechIndicator.values || !this.currentTechIndicator.values.length) {
        return '-';
      }
      return this.currentTechIndicator.values[0].value || '-';
    },
    // 判断是否为直接映射
    isDirectMapping() {
      if (!this.selectedDemands.length || !this.selectedInds.length) return false;

      // 检查选中的需求是否全部为文本类型
      return this.selectedDemands.every(demand => demand.type === 'text') &&
             this.selectedInds.every(ind => ind.type === 'text');
    },

    // 判断是否为选项映射
    isOptionMapping() {
      if (!this.selectedDemands.length || !this.selectedInds.length) return false;

      // 检查是否至少有一个选项或范围类型
      return this.selectedDemands.some(demand =>
               demand.type === 'option' || demand.type === 'range'
             ) &&
             this.selectedInds.some(ind =>
               ind.type === 'option'
             );
    },
    
    // 是否可以创建函数映射
    canCreateFunctionMapping() {
      return this.selectedDemands.length > 0 && this.selectedInds.length === 1;
    },
    
    // 智能判断当前映射类型
    currentMappingType() {
      if (!this.selectedDemands.length || !this.selectedInds.length) return null;
      
      // 检查是否为数字类型 - 函数映射
      if (this.selectedDemands.some(demand => demand.type === 'num') &&
          this.selectedInds.some(ind => ind.type === 'num')) {
        return 'function';
      }
      
      // 检查是否为文本类型 - 直接映射
      if (this.selectedDemands.every(demand => demand.type === 'text') &&
          this.selectedInds.every(ind => ind.type === 'text')) {
        return 'direct';
      }
      
      // 检查是否为选项或范围类型 - 知识映射
      if ((this.selectedDemands.some(demand => demand.type === 'option' || demand.type === 'range')) &&
          this.selectedInds.some(ind => ind.type === 'option')) {
        return 'knowledge';
      }
      
      return null;
    },
    
    // 映射按钮文本
    mappingButtonText() {
      if (!this.currentMappingType) return '配置映射';
      
      switch(this.currentMappingType) {
        case 'direct': return '配置直接映射';
        case 'knowledge': return '配置知识映射';
        case 'function': return '配置函数映射';
        default: return '配置映射';
      }
    },
    
    // 映射按钮图标
    mappingButtonIcon() {
      if (!this.currentMappingType) return 'el-icon-connection';
      
      switch(this.currentMappingType) {
        case 'direct': return 'el-icon-link';
        case 'knowledge': return 'el-icon-collection-tag';
        case 'function': return 'el-icon-s-operation';
        default: return 'el-icon-connection';
      }
    },
    
    // 判断映射按钮是否可用
    canConfigureMapping() {
      return this.selectedDemands.length > 0 && this.selectedInds.length > 0;
    }
  },
  watch: {
    structName(val) {
      this.$refs.structTree.filter(val);
    }
  },
  created() {
    this.getStructTree();
    this.getTechTree();
    this.getMappingList();
    this.loadMappingData();
    if (this.currentStruct && this.currentStruct.id) {
      this.loadMappingList(this.currentStruct.id);
    }
  },
  methods: {
    /** 获取结构树数据 */
    getStructTree() {
      this.loading = true;
      listStruct().then(response => {
        this.structOptions = this.handleTree(response.data, "id", "pid");
        this.loading = false;
      });
    },

    /** 过滤结构树节点 */
    filterStructNode(value, data) {
      if (!value) return true;
      return data.name.toLowerCase().includes(value.toLowerCase());
    },

    /** 结构树节点点击事件 */
    handleStructNodeClick(data) {
      this.currentStruct = data;
      this.loadDemandList(data.id);
      this.loadIndList(data.id);
      this.loadMappingList(data.id);  // Make sure this is called to load function mappings
    },

    /** 加载需求列表 */
    loadDemandList(structId) {
      this.demandLoading = true;
      getStructDemandByStructId(structId).then(async response => {
        try {
          const demandResponse = await listDemand();
          const demandMap = {};
          demandResponse.data.forEach(demand => {
            demandMap[demand.id] = demand;
          });

          // 按需求分组处理值
          const groupedDemands = {};
          response.data.forEach(item => {
            const demandDetail = demandMap[item.did] || {};
            const key = item.did;

            if (!groupedDemands[key]) {
              groupedDemands[key] = {
                ...item,
                name: demandDetail.name || '未知需求',
                type: demandDetail.type || 'text',
                values: [],
                isMapped: false // 初始化映射状态为否
              };
            }

            if (item.value) {
              groupedDemands[key].values.push({
                id: item.id,
                value: item.value
              });
            }
          });

          this.demandList = Object.values(groupedDemands);

          // 检查文本类型需求的映射状态
          for (const demand of this.demandList) {
            if (demand.type === 'text') {
              try {
                const checkResult = await checkDemandMapped(demand.id);
                demand.isMapped = checkResult.data;
                this.mappedDemands[demand.id] = demand.isMapped;
              } catch (err) {
                console.error('检查需求映射状态失败:', err);
              }
            }
          }
          
          this.demandLoading = false;
        } catch (error) {
          console.error('获取需求详情失败:', error);
          this.$message.error("加载需求失败");
          this.demandLoading = false;
        }
      });
    },

    /** 加载技术指标列表 */
    loadIndList(structId) {
      this.indLoading = true;
      getStructIndByStructId(structId).then(async response => {
        try {
          const indResponse = await listInd();
          const indMap = {};
          indResponse.data.forEach(ind => {
            indMap[ind.id] = ind;
          });

          // 按技术指标分组处理值
          const groupedInds = {};
          response.data.forEach(item => {
            const indDetail = indMap[item.iid] || {};
            const key = item.iid;

            if (!groupedInds[key]) {
              groupedInds[key] = {
                ...item,
                name: indDetail.name || '未知指标',
                type: indDetail.type || 'text',
                values: [],
                isMapped: false // 初始化映射状态为否
              };
            }

            if (item.value) {
              groupedInds[key].values.push({
                id: item.id,
                value: item.value
              });
            }
          });

          this.indList = Object.values(groupedInds);

          // 检查文本类型指标的映射状态
          for (const ind of this.indList) {
            if (ind.type === 'text') {
              try {
                const checkResult = await checkIndicatorMapped(ind.id);
                ind.isMapped = checkResult.data;
                this.mappedIndicators[ind.id] = ind.isMapped;
              } catch (err) {
                console.error('检查指标映射状态失败:', err);
              }
            }
          }
          
          this.indLoading = false;
        } catch (error) {
          console.error('获取技术指标详情失败:', error);
          this.$message.error("加载技术指标失败");
          this.indLoading = false;
        }
      });
    },

    /** 判断技术指标是否可选 */
    isIndicatorSelectable(row) {
      // Check if mapped in direct relationship
      if (this.mappedIndicators[row.id] && row.type === 'text') {
        return false;
      }
      
      // Type compatibility checks with already selected items
      if (this.selectedInds.length > 0) {
        const firstType = this.selectedInds[0].type;
        return row.type === firstType;
      }
      
      return true;
    },

    /** 获取行的类名 */
    getRowClassName(row) {
      // 如果已映射，添加映射类名
      if (row.isMapped) {
        return 'mapped-row';
      }

      if (this.selectedDemands && this.selectedDemands.length > 0) {
        const hasTextDemand = this.selectedDemands.some(demand => demand.type === 'text');
        const hasNumDemand = this.selectedDemands.some(demand => demand.type === 'num');
        const hasRangeOrOptionDemand = this.selectedDemands.some(
          demand => demand.type === 'range' || demand.type === 'option'
        );

        if ((hasTextDemand && row.type !== 'text') ||
            (hasNumDemand && row.type !== 'num') ||
            (hasRangeOrOptionDemand && row.type !== 'option')) {
          return 'disabled-row';
        }
      }
      return '';
    },

    /** 需求选择变化事件 */
    handleDemandSelectionChange(selection) {
      // 过滤掉已映射的需求
      selection = selection.filter(item => !item.isMapped);

      // 如果没有选择，直接更新
      if (selection.length === 0) {
        this.selectedDemands = selection;
        return;
      }

      // 获取最新选择的项
      const latestSelected = selection[selection.length - 1];

      // 如果是文本或选项类型，只允许选择一个
      if (latestSelected.type === 'text' || latestSelected.type === 'option') {
        this.selectedDemands = [latestSelected];
      } else {
        this.selectedDemands = selection;
      }

      // 清除已选的技术指标
      if (this.$refs.indTable) {
        this.$refs.indTable.clearSelection();
      }
    },

    /** 技术指标选择变化事件 */
    handleIndSelectionChange(selection) {
      // 如果没有选择，直接更新
      if (selection.length === 0) {
        this.selectedInds = selection;
        return;
      }

      // 获取最新选择的项
      const latestSelected = selection[selection.length - 1];

      // 如果是文本或选项类型，只允许选择一个
      if (latestSelected.type === 'text' || latestSelected.type === 'option') {
        this.selectedInds = [latestSelected];
      } else {
        // 过滤掉不可选的行
        this.selectedInds = selection.filter(row => this.isIndicatorSelectable(row));
      }
    },

    /** 获取文本值 */
    getTextValue(values) {
      if (!values || !Array.isArray(values) || values.length === 0) {
        return '-';
      }
      // 如果value是直接的值而不是对象
      if (typeof values[0] === 'string') {
        return values[0] || '-';
      }
      // 如果value是对象
      return values[0].value || '-';
    },

    /** 获取选项数量 */
    getOptionsCount(row) {
      return row.values ? row.values.length : 0;
    },

    /** 获取范围数量 */
    getRangeCount(row) {
      return row.values ? row.values.length : 0;
    },

    /** 查询技术指标树结构 */
    getTechTree() {
      listInd().then(response => {
        this.techOptions = this.handleTree(response.data, "id", "pid");
      });
    },

    /** 获取映射关系列表 */
    getMappingList() {
      // 这里应该调用后端API获取映射关系
      // 暂时使用模拟数据
      this.mappingList = [
        { id: 1, requirement: '需求A', mappingType: '直接映射', techIndicator: '技术指标X' },
        { id: 2, requirement: '需求B', mappingType: '条件映射', techIndicator: '技术指标Y' },
        { id: 3, requirement: '需求C', mappingType: '组合映射', techIndicator: '技术指标Z' },
        { id: 4, requirement: '需求D', mappingType: '拆分映射', techIndicator: '技术指标W' }
      ];
    },

    /** 加载映射列表 */
    loadMappingList(structId) {
      if (structId) {
        // Get function mappings for this structure
        getFunctionMappingBySid(structId).then(response => {
          this.functionMappings = response.data || [];
          
          // Process mappings to identify which demands and indicators are already mapped
          this.functionMappings.forEach(mapping => {
            if (mapping.sdid) {
              // Mark demand as mapped in function relationship
              this.functionMappedDemands[mapping.sdid] = true;
            }
            if (mapping.siid) {
              // Mark indicator as mapped in function relationship
              this.functionMappedIndicators[mapping.siid] = true;
              
              // Force UI to update
              this.$nextTick(() => {
                this.$forceUpdate();
              });
            }
          });
        });
      }
    },

    /** 加载已有的知识映射关系 */
    loadExistingKnowledgeMappings() {
      // 清空现有数据
      this.existingMappings = [];
      this.mappedDemandOptions = {}; // 重置已映射选项记录
      
      if (!this.currentStruct || !this.selectedDemands || !this.selectedDemands.length || 
          !this.selectedInds || !this.selectedInds.length) {
        console.log("加载条件不满足，跳过加载");
        return;
      }

      const sid = this.currentStruct.id;
      const did = this.selectedDemands[0].did || this.selectedDemands[0].id;
      const iid = this.selectedInds[0].iid || this.selectedInds[0].id;

      console.log('开始加载映射关系 - 参数:', {sid, did, iid});
      
      const params = { sid, did, iid };
      const loading = this.$loading({
        lock: true,
        text: '加载映射数据中...',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.7)'
      });

      // 调用API
      getKnowledgeMappingsByStructAndDemandAndIndicator(params)
        .then(response => {
          loading.close();
          console.log('API返回数据:', response);
          
          if (!response || !response.data) {
            console.warn('API返回数据为空');
            this.existingMappings = [];
            return;
          }
          
          // 统一数据格式
          const formattedData = response.data.map(item => {
            // 记录已映射的需求选项ID - 确保使用正确的ID
            const doid = item.doid || item.demand_option_id;
            if (doid) {
              this.mappedDemandOptions[doid] = true;
              console.log('标记已映射的需求选项:', doid);
            }
            
            return {
              id: item.id,
              demandName: item.demandName || item.demand_name || '',
              demandOptionValue: item.demandOptionValue || item.demand_option_value || '',
              indicatorName: item.indicatorName || item.indicator_name || '',
              indicatorOptionValue: item.indicatorOptionValue || item.indicator_option_value || '',
              doid: item.doid || '',
              ioid: item.ioid || ''
            };
          });
          
          // 更新数据
          this.existingMappings = formattedData;
          
          console.log('数据处理完成, 映射数:', this.existingMappings.length);
          console.log('已映射的需求选项IDs:', this.mappedDemandOptions);
          
          // 强制视图更新
          this.$nextTick(() => {
            this.$forceUpdate();
          });
        })
        .catch(error => {
          loading.close();
          console.error('加载映射关系失败:', error);
          this.$message.error('加载映射关系失败: ' + (error.message || '未知错误'));
          this.existingMappings = [];
        });
    },

    /** 添加一对一的映射 */
    addOneToOneMapping() {
      if (!this.currentDemandOption || !this.currentIndicatorOption) {
        this.$message.warning("请先选择需求选项和指标选项");
        return;
      }
      
      // 再次检查需求选项是否已有映射
      const doid = this.currentDemandOption.doid || this.currentDemandOption.id;
      if (this.mappedDemandOptions[doid]) {
        this.$message.warning('该需求选项已有映射关系，不能重复配置');
        return;
      }

      this.addMappingLoading = true;

      // 获取选中的需求和技术指标
      const demand = this.selectedDemands[0];
      const indicator = this.selectedInds[0];

      // 修正映射数据参数，移除sdid和siid字段
      const mappingData = {
        sid: this.currentStruct.id,
        // 直接使用选项ID
        doid: this.currentDemandOption.doid || this.currentDemandOption.id,
        demandOptionValue: this.currentDemandOption.value,
        // 直接使用选项ID
        ioid: this.currentIndicatorOption.ioid || this.currentIndicatorOption.id,
        indicatorOptionValue: this.currentIndicatorOption.value
      };

      console.log("添加映射数据:", mappingData);

      addKnowledgeMapping(mappingData).then(response => {
        this.$message.success("添加映射成功");
        this.addMappingLoading = false;

        // 重新加载映射关系
        this.loadExistingKnowledgeMappings();

        // 清除选择状态
        this.currentDemandOption = null;
        this.currentIndicatorOption = null;
        this.$refs.demandOptionTable.setCurrentRow(null);
        this.$refs.indicatorOptionTable.setCurrentRow(null);
      }).catch(error => {
        console.error("添加映射失败:", error);
        this.$message.error("添加映射失败：" + (error.message || "未知错误"));
        this.addMappingLoading = false;
      });
    },

    /** 删除映射关系 */
    removeMapping(id) {
      this.$confirm('确定要删除此映射关系吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        return delKnowledgeMapping(id);
      }).then(() => {
        this.$message.success("删除成功");
        
        // 重新加载映射关系
        this.loadExistingKnowledgeMappings();
      }).catch(() => {});
    },

    /** 处理需求选项行点击 */
    handleDemandOptionRowClick(row) {
      // 检查该选项是否已映射
      const doid = row.doid || row.id;
      if (this.mappedDemandOptions[doid]) {
        this.$message.warning('该需求选项已有映射关系，不能重复配置');
        // 清除选择状态，防止用户继续操作
        this.$refs.demandOptionTable.setCurrentRow(null);
        return;
      }
      
      this.currentDemandOption = row;
      
      // 如果已经选择了技术指标选项，自动添加映射关系
      if (this.currentIndicatorOption) {
        this.addOneToOneMapping();
      }
    },

    /** 获取需求选项行的CSS类名 */
    getDemandOptionRowClass({ row }) {
      // 检查该需求选项是否已映射
      const doid = row.doid || row.id;
      if (this.mappedDemandOptions[doid]) {
        return 'mapped-option-row';
      }
      return '';
    },

    /** 处理技术指标选项行点击 */
    handleIndicatorOptionRowClick(row) {
      this.currentIndicatorOption = row;

      // 如果已经选择了需求选项，自动添加映射关系
      if (this.currentDemandOption) {
        this.addOneToOneMapping();
      }
    },

    /** 处理添加映射按钮点击 - 智能分发到不同的映射处理 */
    handleAddMapping() {
      if (!this.selectedDemands.length || !this.selectedInds.length) {
        this.$message.warning('请选择需求和技术指标');
        return;
      }
      
      // 判断应该使用哪种映射类型
      let mappingType = this.determineMappingType();
      
      // 根据判断的映射类型处理
      switch(mappingType) {
        case 'direct':
          // 处理直接映射
          this.mappingDialog.title = '配置直接映射';
          this.mappingDialog.visible = true;
          break;
          
        case 'knowledge':
          // 选项映射逻辑
          this.mappingDialog.title = '配置知识映射';
          
          // 只允许选择一项需求和一项指标进行选项映射
          if (this.selectedDemands.length > 1 || this.selectedInds.length > 1) {
            this.$message.warning('选项映射只能选择一个需求和一个技术指标');
            return;
          }
          
          // 显示对话框前先清空数据
          this.existingMappings = [];
          this.mappingDialog.visible = true;
          
          // 对话框显示后再加载数据
          this.$nextTick(() => {
            this.loadDemandOptions(this.selectedDemands[0].did);
            this.loadIndicatorOptions(this.selectedInds[0].iid);
            this.loadExistingKnowledgeMappings();
          });
          break;
          
        case 'function':
          // 函数映射逻辑
          this.openFunctionMappingDialog();
          break;
          
        default:
          this.$message.warning('选择的需求和技术指标类型不兼容，无法配置映射');
          break;
      }
    },

    /** 判断应该使用的映射类型 */
    determineMappingType() {
      // 检查是否为数值类型 - 函数映射
      if (this.selectedDemands.some(demand => demand.type === 'num') &&
          this.selectedInds.some(ind => ind.type === 'num')) {
        return 'function';
      }
      
      // 检查是否为文本类型 - 直接映射
      if (this.selectedDemands.every(demand => demand.type === 'text') &&
          this.selectedInds.every(ind => ind.type === 'text')) {
        return 'direct';
      }
      
      // 检查是否为选项或范围类型 - 知识映射
      if ((this.selectedDemands.some(demand => demand.type === 'option' || demand.type === 'range')) &&
          this.selectedInds.some(ind => ind.type === 'option')) {
        return 'knowledge';
      }
      
      return null;
    },

    /** 确认映射 */
    confirmMapping() {
      this.mappingDialog.loading = true;

      if (this.isDirectMapping) {
        // 直接映射处理逻辑 - 保持现有代码
        // 构建映射数据 - 为每个需求和指标的组合创建一个映射记录
        const mappingRequests = [];

        this.selectedDemands.forEach(demand => {
          this.selectedInds.forEach(ind => {
            mappingRequests.push({
              sid: this.currentStruct.id,  // 添加结构ID
              sdid: demand.id || demand.did,             // 结构需求ID
              siid: ind.id || ind.iid                 // 结构指标ID
            });
          });
        });

        // 发送单个映射请求
        const sendMappingRequest = (mappingData) => {
          return addDirectMapping(mappingData);
        };

        // 串行处理所有映射请求
        const processMappings = async () => {
          try {
            for (const mappingData of mappingRequests) {
              await sendMappingRequest(mappingData);
            }
            this.$modal.msgSuccess("配置映射成功");
            this.mappingDialog.visible = false;
            // 清空选择
            this.selectedDemands = [];
            this.selectedInds = [];
            if (this.$refs.indTable) {
              this.$refs.indTable.clearSelection();
            }
            // 重新加载数据
            this.loadDemandList(this.currentStruct.id);
            this.loadIndList(this.currentStruct.id);
          } catch (error) {
            console.error('Mapping Error:', error.response || error);
            this.$modal.msgError(`配置映射失败: ${error.response?.data?.message || error.message || '未知错误'}`);
          } finally {
            this.mappingDialog.loading = false;
          }
        };

        processMappings();
      } else if (this.isOptionMapping) {
        // 选项映射处理逻辑 - 现在只需要关闭对话框，因为映射已经在添加时保存
        this.mappingDialog.visible = false;
        this.mappingDialog.loading = false;

        // 清空选择
        this.selectedDemands = [];
        this.selectedInds = [];
        if (this.$refs.demandTable) {
          this.$refs.demandTable.clearSelection();
        }
        if (this.$refs.indTable) {
          this.$refs.indTable.clearSelection();
        }

        // 重新加载数据
        this.loadDemandList(this.currentStruct.id);
        this.loadIndList(this.currentStruct.id);
      } else {
        this.mappingDialog.loading = false;
        this.$message.warning('请至少添加一个映射关系');
      }
    },

    /** 取消映射 */
    cancelMapping() {
      this.mappingDialog.visible = false;
      this.mappingDialog.loading = false;
      this.knowledgeMappings = [];
      this.selectedDemandOptions = [];
      this.selectedIndicatorOptions = [];
    },

    /** 加载映射数据 */
    loadMappingData() {
      // 重新加载映射列表的逻辑
      // ...
    },

    /** 获取类型名称 */
    getTypeName(type) {
      switch(type) {
        case 'text': return '文本';
        case 'num': return '数字';
        case 'range': return '范围';
        case 'option': return '选项';
        default: return '未知';
      }
    },

    /** 获取选项提示内容 */
    getOptionsTooltip(row) {
      if (!row.values || row.values.length === 0) return '';
      return row.values.map(v => v.value).join('\n');
    },

    /** 获取范围提示内容 */
    getRangeTooltip(row) {
      if (!row.values || row.values.length === 0) return '';
      return row.values.map(v => v.value.replace('-', ' - ')).join('\n');
    },

    /** 判断需求是否可选 */
    isDemandSelectable(row) {
      // Check if mapped in direct relationship
      if (row.isMapped && row.type === 'text') {
        return false;
      }
      
      // Type compatibility checks with already selected items
      if (this.selectedDemands.length > 0) {
        const firstType = this.selectedDemands[0].type;
        return row.type === firstType;
      }
      
      return true;
    },

    /** 获取行的类名 - 用于需求表格 */
    getDemandRowClassName(row) {
      // 如果已映射，添加映射类名
      if (row.isMapped) {
        return 'mapped-row';
      }
      return '';
    },

    /** 处理需求复选框变更 */
    handleCheckboxChange(value, row, index) {
      // Use the correct ref (demandTable)
      this.$refs.demandTable.toggleRowSelection(row, value);
    },

    /** 处理指标复选框变更 */
    handleIndCheckboxChange(value, row, index) {
      this.$refs.indTable.toggleRowSelection(row, value);
    },

    /** 加载需求选项 */
    loadDemandOptions(demandId) {
      if (!this.currentStruct || !demandId) return;

      this.loadingDemandOptions = true;
      this.demandOptions = [];

      console.log('正在加载需求选项, 结构ID:', this.currentStruct.id, '需求ID:', demandId);

      getDemandOptions(this.currentStruct.id, demandId)
        .then(response => {
          console.log('需求选项加载结果:', response);
          const options = response.data || [];
          this.demandOptions = options.filter(option => {
            return option && option.value !== undefined && option.value !== null && option.value.trim() !== '';
          }).map(option => {
            return {
              // 移除sdid字段
              doid: option.doid || option.id,  // 需求选项ID，确保获取正确ID
              value: option.value.trim(),
              demandId: demandId
            };
          });

          console.log('处理后的需求选项:', this.demandOptions);

          if (this.demandOptions.length === 0) {
            this.$message.warning('该需求没有有效的选项值');
          }
        })
        .catch(error => {
          console.error('获取需求选项失败:', error);
          this.$message.error('加载需求选项失败');
        })
        .finally(() => {
          this.loadingDemandOptions = false;
        });
    },

    /** 加载技术指标选项 */
    loadIndicatorOptions(indicatorId) {
      if (!this.currentStruct || !indicatorId) return;

      this.loadingIndicatorOptions = true;
      this.indicatorOptions = [];

      console.log('正在加载指标选项, 结构ID:', this.currentStruct.id, '指标ID:', indicatorId);

      getIndicatorOptions(this.currentStruct.id, indicatorId)
        .then(response => {
          console.log('指标选项加载结果:', response);
          const options = response.data || [];
          this.indicatorOptions = options.filter(option => {
            return option && option.value !== undefined && option.value !== null && option.value.trim() !== '';
          }).map(option => {
            return {
              // 移除siid字段
              ioid: option.ioid || option.id,  // 指标选项ID，确保获取正确ID
              value: option.value.trim(),
              indicatorId: indicatorId
            };
          });

          console.log('处理后的指标选项:', this.indicatorOptions);

          if (this.indicatorOptions.length === 0) {
            this.$message.warning('该技术指标没有有效的选项值');
          }
        })
        .catch(error => {
          console.error('获取指标选项失败:', error);
          this.$message.error('加载指标选项失败');
        })
        .finally(() => {
          this.loadingIndicatorOptions = false;
        });
    },

    /** 需求选项选择变化处理 */
    handleDemandOptionSelect(row) {
      if (!row) {
        this.currentDemandOption = null;
        return;
      }

      // 确保选项ID被正确获取，移除sdid引用
      this.currentDemandOption = {
        doid: row.doid || row.id,  // 需求选项ID
        value: row.value,
        demandId: this.selectedDemands[0].did
      };

      console.log('选中需求选项:', {
        '需求选项ID': this.currentDemandOption.doid,
        '选项值': this.currentDemandOption.value,
        '需求ID': this.currentDemandOption.demandId
      });
    },

    /** 指标选项选择变化处理 */
    handleIndicatorOptionSelect(row) {
      if (!row) {
        this.currentIndicatorOption = null;
        return;
      }

      // 确保选项ID被正确获取，移除siid引用
      this.currentIndicatorOption = {
        ioid: row.ioid || row.id,  // 指标选项ID
        value: row.value,
        indicatorId: this.selectedInds[0].iid
      };

      console.log('选中指标选项:', {
        '指标选项ID': this.currentIndicatorOption.ioid,
        '选项值': this.currentIndicatorOption.value,
        '指标ID': this.currentIndicatorOption.indicatorId
      });
    },

    /** 获取需求禁用原因文本 */
    getDemandDisabledReason(row) {
      if (row.isMapped && row.type === 'text') {
        return '该需求已配置直接映射关系';
      }
      
      if (this.selectedDemands.length > 0) {
        const selectedType = this.selectedDemands[0].type;
        return `只能选择${this.getTypeName(selectedType)}类型的需求`;
      }

      if (this.selectedInds.length > 0) {
        const selectedType = this.selectedInds[0].type;

        if (selectedType === 'text') {
          return '当前已选择文本类型的技术指标，只能选择文本类型的需求';
        } else if (selectedType === 'num') {
          return '当前已选择数字类型的技术指标，只能选择数字类型的需求';
        } else if (selectedType === 'option') {
          return '当前已选择选项类型的技术指标，只能选择选项或范围类型的需求';
        }
      }

      return '该需求不可选';
    },

    /** 获取指标禁用原因文本 */
    getIndicatorDisabledReason(row) {
      if (row.isMapped && row.type === 'text') {
        return '该指标已配置直接映射关系';
      }
      
      if (this.selectedInds.length > 0) {
        const selectedType = this.selectedInds[0].type;
        return `只能选择${this.getTypeName(selectedType)}类型的技术指标`;
      }

      if (this.selectedDemands.length > 0) {
        const selectedType = this.selectedDemands[0].type;

        if (selectedType === 'text') {
          return '当前已选择文本类型的需求，只能选择文本类型的技术指标';
        } else if (selectedType === 'num') {
          return '当前已选择数字类型的需求，只能选择数字类型的技术指标';
        } else if (selectedType === 'option' || selectedType === 'range') {
          return '当前已选择选项或范围类型的需求，只能选择选项类型的技术指标';
        }
      }

      return '该技术指标不可选';
    },

    /** 检查选项是否已经被映射 */
    isOptionMapped(option, type) {
      if (!option || !this.knowledgeMappings.length) return false;

      if (type === 'demand') {
        return this.knowledgeMappings.some(mapping =>
          mapping.doid === option.doid ||
          (mapping.demandOptionValue === option.value && option.value)
        );
      } else {
        // For indicator options, can be mapped multiple times
        return false;
      }
    },

    /** 处理映射对话框打开事件 */
    handleMappingDialogOpen() {
      if (this.isOptionMapping) {
        // 加载需求选项和指标选项
        this.loadDemandOptions();
        this.loadIndicatorOptions();

        // 使用getKnowledgeMappingsByDemandAndIndicator加载已有映射关系
        this.loadExistingKnowledgeMappings();
      }
    },

    // 调试方法 - 问题解决后可移除
    showDebugData() {
      console.log("当前映射数据:", this.existingMappings);
      this.$alert(
        `<pre>${JSON.stringify(this.existingMappings, null, 2)}</pre>`, 
        '映射数据详情', 
        {
          dangerouslyUseHTMLString: true,
          closeOnClickModal: true
        }
      );
    },

    /** 获取需求选项行的CSS类名 */
    getDemandOptionRowClass({ row }) {
      // 检查该需求选项是否已映射
      const doid = row.doid || row.id;
      if (this.mappedDemandOptions[doid]) {
        return 'mapped-option-row';
      }
      return '';
    },

    // 判断需求是否为数字类型
    isDemandNumericType(row) {
      return row.type === 'num';
    },
    
    // 判断指标是否为数字类型
    isIndicatorNumericType(row) {
      return row.type === 'num';
    },
    
    // 处理需求选择变更
    handleDemandSelectionChange(selection) {
      this.selectedDemands = selection.map(item => {
        // 为每个需求添加变量名和测试值属性
        return {
          ...item,
          varName: 'x' + (this.selectedDemands.length + 1),
          testValue: 0
        };
      });
    },
    
    // 处理指标选择变更
    handleIndSelectionChange(selection) {
      this.selectedInds = selection;
    },
    
    // 获取行的类名
    getDemandRowClassName(row) {
      return row.row.isMapped ? 'mapped-row' : '';
    },
    
    // 获取类型名称
    getTypeName(type) {
      return type === 'num' ? '数值型' : '文本型';
    },
    
    // 打开函数映射对话框
    openFunctionMappingDialog() {
      if (!this.canCreateFunctionMapping) {
        this.$message.warning('请选择数字类型的需求和指标');
        return;
      }
      
      // 初始化变量名
      this.selectedDemands.forEach((demand, index) => {
        demand.varName = 'x' + (index + 1);
        demand.testValue = null;
      });
      
      // 初始化表单
      this.functionForm = {
        id: null,
        formula: '',
        unit: '',
        testActive: [],
        testResult: null
      };
      
      // 显示对话框
      this.functionDialog.visible = true;
    },
    
    // 测试公式
    testFormula() {
      if (!this.functionForm.formula) {
        this.$message.warning('请输入公式');
        return;
      }
      
      // 检查变量值是否都已填写
      let allFilled = true;
      const vars = {};
      
      this.selectedDemands.forEach(demand => {
        if (demand.testValue === null || demand.testValue === '') {
          allFilled = false;
          this.$message.warning(`请输入变量 ${demand.varName} 的值`);
          return;
        }
        
        vars[demand.varName] = demand.testValue;
      });
      
      if (!allFilled) return;
      
      try {
        // 计算公式结果
        const result = this.evaluateFormula(this.functionForm.formula, vars);
        this.functionForm.testResult = result;
      } catch (error) {
        console.error('公式计算错误:', error);
        this.$message.error('公式计算错误: ' + error.message);
      }
    },
    
    // 公式求值
    evaluateFormula(formula, vars) {
      let evalFormula = formula;
      
      for (const [name, value] of Object.entries(vars)) {
        // 正则表达式确保只替换整个变量名而不是变量名的一部分
        const regex = new RegExp('\\b' + name + '\\b', 'g');
        evalFormula = evalFormula.replace(regex, value);
      }
      
      // 添加数学函数
      evalFormula = 'with(Math){return ' + evalFormula + '}';
      
      // 使用Function构造函数而不是eval(相对安全一些)
      const func = new Function(evalFormula);
      
      return func();
    },
    
    // 保存函数映射 - 批量保存所有选中的需求
    saveFunctionMapping() {
      // 检查公式是否为空
      if (!this.functionForm.formula || this.functionForm.formula.trim() === '') {
        this.$message.warning('请输入有效的公式');
        return;
      }
      
      // 添加正则表达式验证公式的合法性
      const formula = this.functionForm.formula.trim();
      
      // 检查公式是否包含非法字符
      const validCharsRegex = /^[a-zA-Z0-9\s\+\-\*\/\(\)\.\,\_\[\]\{\}sin|cos|tan|log|ln|exp|sqrt|pow|abs|max|min|round|floor|ceil]+$/;
      if (!validCharsRegex.test(formula)) {
        this.$message.warning('公式包含非法字符，请仅使用数字、字母、运算符和函数名');
        return;
      }
      
      // 检查括号是否匹配
      if (!this.checkBracketBalance(formula)) {
        this.$message.warning('公式中的括号不匹配，请检查');
        return;
      }
      
      // 检查变量名是否都存在
      const variableRegex = /\b([a-zA-Z][a-zA-Z0-9_]*)\b/g;
      const matches = formula.match(variableRegex) || [];
      const variables = new Set(matches);
      
      // 从变量集合中移除函数名
      const functions = ['sin', 'cos', 'tan', 'log', 'ln', 'exp', 'sqrt', 'pow', 'abs', 'max', 'min', 'round', 'floor', 'ceil'];
      functions.forEach(func => variables.delete(func));
      
      // 检查所有的变量是否存在于选中的需求中
      const validVariables = this.selectedDemands.map(demand => demand.varName);
      for (const variable of variables) {
        if (!validVariables.includes(variable) && !functions.includes(variable)) {
          this.$message.warning(`公式中的变量"${variable}"不存在，请检查`);
          return;
        }
      }
      
      // 检查公式的语法是否正确（通过尝试解析）
      try {
        // 构造一个测试公式，所有变量替换为数字1进行测试
        let testFormula = formula;
        for (const variable of variables) {
          if (!functions.includes(variable)) {
            const regex = new RegExp('\\b' + variable + '\\b', 'g');
            testFormula = testFormula.replace(regex, '1');
          }
        }
        
        // 尝试计算
        const evalTest = 'with(Math){return ' + testFormula + '}';
        new Function(evalTest)();
      } catch (e) {
        this.$message.warning('公式语法不正确，请检查: ' + e.message);
        return;
      }
      
      // 现有的代码继续...
      try {
        this.functionDialog.loading = true;
        const selectedIndicator = this.selectedInds[0];
        
        // 为每个选中的需求创建一个映射记录
        const mappingList = this.selectedDemands.map((demand, index) => {
          // 简化变量名生成
          const variableName = `x${index + 1}`;
          
          // 返回映射对象
          return {
            sid: this.currentStruct.id,
            sdid: demand.did || demand.id,
            siid: selectedIndicator.iid || selectedIndicator.id,
            formula: formula,
            unit: this.functionForm.unit || '',
            variable: variableName,
            cnt: this.selectedDemands.length  // 添加参数cnt，表示需求总数
          };
        });
        
        // 使用API发送请求
        import('@/api/data/function_mapping').then(api => {
          api.batchAddFunctionMapping(mappingList)
            .then(response => {
              this.$message.success(`成功创建${mappingList.length}个函数映射关系`);
              this.functionDialog.visible = false;
              
              // 刷新数据
              if (this.currentStruct) {
                this.loadDemandList(this.currentStruct.id);
                this.loadIndList(this.currentStruct.id);
                this.loadMappingList(this.currentStruct.id);
              }
              
              // 清空选择
              this.clearSelections();
            })
            .catch(error => {
              let errorMsg = '批量保存失败';
              if (error.response?.data?.message) {
                errorMsg += ': ' + error.response.data.message;
              } else if (error.response?.data?.msg) {
                errorMsg += ': ' + error.response.data.msg;
              } else if (error.message) {
                errorMsg += ': ' + error.message;
              }
              this.$message.error(errorMsg);
            })
            .finally(() => {
              this.functionDialog.loading = false;
            });
        }).catch(error => {
          this.$message.error('导入API模块失败: ' + error.message);
          this.functionDialog.loading = false;
        });
      } catch (e) {
        this.$message.error('数据处理出错: ' + e.message);
        this.functionDialog.loading = false;
      }
    },
    
    // 清除选择
    clearSelections() {
      this.selectedDemands = [];
      this.selectedInds = [];
      if (this.$refs.demandTable) {
        this.$refs.demandTable.clearSelection();
      }
      if (this.$refs.indTable) {
        this.$refs.indTable.clearSelection();
      }
    },
    
    /** 获取映射类型名称 */
    getMappingTypeName(type) {
      switch(type) {
        case 'direct': return '直接映射';
        case 'knowledge': return '知识映射';
        case 'function': return '函数映射';
        default: return '未知类型';
      }
    },
    
    // 加载结构详情后调用，获取所有已配置的映射
    loadConfiguredMappings() {
      if (!this.currentStruct || !this.currentStruct.id) return;
      
      // 获取当前结构下所有的映射
      this.$axios.post('/system/mapping/list', { sid: this.currentStruct.id })
        .then(response => {
          console.log('已配置的映射:', response.data);
          this.configuredMappings = response.data.rows || [];
          
          // 更新需求和指标的状态
          this.updateDemandIndicatorStatus();
        })
        .catch(error => {
          console.error('获取映射配置失败:', error);
        });
    },
    
    // 更新需求和指标的映射状态
    updateDemandIndicatorStatus() {
      // 更新需求状态
      if (this.demands && this.demands.length > 0) {
        this.demands.forEach(demand => {
          // 只考虑数字类型需求
          if (demand.dataType === 'NUMBER') {
            // 检查此需求是否已被映射
            const isMapped = this.configuredMappings.some(mapping => 
              mapping.sdid === demand.did || (mapping.sdids && mapping.sdids.split(',').includes(demand.did))
            );
            
            // 设置映射状态
            this.$set(demand, 'isMapped', isMapped);
            this.$set(demand, 'disabled', isMapped);
          }
        });
      }
      
      // 更新指标状态
      if (this.indicators && this.indicators.length > 0) {
        this.indicators.forEach(indicator => {
          // 只考虑数字类型指标
          if (indicator.dataType === 'NUMBER') {
            // 检查此指标是否已被映射
            const isMapped = this.configuredMappings.some(mapping => 
              mapping.siid === indicator.iid
            );
            
            // 设置映射状态
            this.$set(indicator, 'isMapped', isMapped);
            this.$set(indicator, 'disabled', isMapped);
          }
        });
      }
    },
    
    // 加载结构详情后获取映射配置
    loadStructDetail(structId) {
      // ... existing code ...
      
      // 加载完结构详情后，获取映射配置
      this.loadConfiguredMappings();
    },
    
    // 更新表格中的选择禁用状态
    handleSelectionCheck(row, index) {
      // 对于需求表格
      if (this.activeTab === 'demand') {
        // 如果是数字类型需求并且已映射，则禁止选择
        if (row.dataType === 'NUMBER' && row.isMapped) {
          return false;
        }
      }
      // 对于指标表格
      else if (this.activeTab === 'indicator') {
        // 如果是数字类型指标并且已映射，则禁止选择
        if (row.dataType === 'NUMBER' && row.isMapped) {
          return false;
        }
      }
      return true;
    },

    // Add this method or modify if it exists
    selectable(row, index) {
      if (row.type === 'demand') {
        const id = row.id || row.did;
        return !this.functionMappedDemands[id];
      } else if (row.type === 'indicator') {
        const id = row.id || row.iid;
        return !this.functionMappedIndicators[id];
      }
      return true;
    },

    // 加载结构需求数据
    loadStructDemands(structId) {
      this.demandLoading = true;
      getStructDemandByStructId(structId).then(response => {
        this.demandList = response.data.map(item => ({
          ...item,
          type: this.mapDataTypeToType(item.dataType),
          isMapped: false // 初始化映射状态
        }));
        
        // 检查数字类型需求的映射状态
        this.checkNumericDemandsMappingStatus();
        this.demandLoading = false;
      }).catch(error => {
        console.error("获取结构需求失败", error);
        this.demandLoading = false;
      });
    },

    // 加载结构技术指标数据
    loadStructIndicators(structId) {
      this.indLoading = true;
      getStructIndByStructId(structId).then(response => {
        this.indList = response.data.map(item => ({
          ...item,
          type: this.mapDataTypeToType(item.dataType),
          isMapped: false // 初始化映射状态
        }));
        
        // 检查数字类型指标的映射状态
        this.checkNumericIndicatorsMappingStatus();
        this.indLoading = false;
      }).catch(error => {
        console.error("获取结构技术指标失败", error);
        this.indLoading = false;
      });
    },
    
    // 检查数字类型需求的映射状态
    checkNumericDemandsMappingStatus() {
      if (!this.currentStruct || !this.demandList || this.demandList.length === 0) return;
      
      // 过滤出数字类型的需求
      const numTypeDemands = this.demandList.filter(item => item.type === 'num');
      if (numTypeDemands.length === 0) return;
      
      // 对每个数字类型的需求检查映射状态
      numTypeDemands.forEach(demand => {
        checkFunctionDemandMapped(demand.did).then(response => {
          if (response.data === true) {
            // 标记为已映射
            const index = this.demandList.findIndex(item => item.did === demand.did);
            if (index !== -1) {
              this.$set(this.demandList[index], 'isMapped', true);
              
              // 如果已映射的需求被选中，取消选择
              const isSelected = this.selectedDemands.some(item => item.did === demand.did);
              if (isSelected) {
                this.$refs.demandTable.toggleRowSelection(this.demandList[index], false);
                this.selectedDemands = this.selectedDemands.filter(item => item.did !== demand.did);
              }
            }
          }
        }).catch(error => {
          console.error('检查需求映射状态失败:', error);
        });
      });
    },
    
    // 检查数字类型指标的映射状态
    checkNumericIndicatorsMappingStatus() {
      if (!this.currentStruct || !this.indList || this.indList.length === 0) return;
      
      // 过滤出数字类型的指标
      const numTypeInds = this.indList.filter(item => item.type === 'num');
      if (numTypeInds.length === 0) return;
      
      // 对每个数字类型的指标检查映射状态
      numTypeInds.forEach(indicator => {
        checkFunctionIndicatorMapped(indicator.iid).then(response => {
          if (response.data === true) {
            // 标记为已映射
            const index = this.indList.findIndex(item => item.iid === indicator.iid);
            if (index !== -1) {
              this.$set(this.indList[index], 'isMapped', true);
              
              // 如果已映射的指标被选中，取消选择
              const isSelected = this.selectedInds.some(item => item.iid === indicator.iid);
              if (isSelected) {
                this.$refs.indTable.toggleRowSelection(this.indList[index], false);
                this.selectedInds = this.selectedInds.filter(item => item.iid !== indicator.iid);
              }
            }
          }
        }).catch(error => {
          console.error('检查指标映射状态失败:', error);
        });
      });
    },
    
    // 检查单个需求是否已映射
    checkSingleDemandMapped(demand) {
      if (!demand || demand.type !== 'num') return Promise.resolve(false);
      
      return checkFunctionDemandMapped(demand.did)
        .then(response => {
          const isMapped = response.data === true;
          this.$set(demand, 'isMapped', isMapped);
          return isMapped;
        })
        .catch(error => {
          console.error('检查需求映射状态失败:', error);
          return false;
        });
    },
    
    // 检查单个指标是否已映射
    checkSingleIndicatorMapped(indicator) {
      if (!indicator || indicator.type !== 'num') return Promise.resolve(false);
      
      return checkFunctionIndicatorMapped(indicator.iid)
        .then(response => {
          const isMapped = response.data === true;
          this.$set(indicator, 'isMapped', isMapped);
          return isMapped;
        })
        .catch(error => {
          console.error('检查指标映射状态失败:', error);
          return false;
        });
    },
    
    // 修改现有的handleDemandSelect方法，添加映射状态检查
    handleDemandSelect(selection, row) {
      // 检查是否为数字类型且已被映射
      if (row.type === 'num') {
        checkFunctionDemandMapped(row.did).then(response => {
          if (response.data === true) {
            // 如果已映射，取消选择并提示用户
            this.$refs.demandTable.toggleRowSelection(row, false);
            this.$message.warning(`需求 "${row.name}" 已被映射，不能重复配置`);
            
            // 更新选中状态
            this.selectedDemands = this.selectedDemands.filter(item => item.did !== row.did);
          } else {
            // 未映射，允许选择
            this.selectedDemands = selection;
          }
        }).catch(error => {
          console.error('检查需求映射状态失败:', error);
          this.selectedDemands = selection;
        });
      } else {
        // 非数字类型，直接更新选择
        this.selectedDemands = selection;
      }
    },
    
    // 修改现有的handleIndSelect方法，添加映射状态检查
    handleIndSelect(selection, row) {
      // 检查是否为数字类型且已被映射
      if (row.type === 'num') {
        checkFunctionIndicatorMapped(row.iid).then(response => {
          if (response.data === true) {
            // 如果已映射，取消选择并提示用户
            this.$refs.indTable.toggleRowSelection(row, false);
            this.$message.warning(`指标 "${row.indicatorName}" 已被映射，不能重复配置`);
            
            // 更新选中状态
            this.selectedInds = this.selectedInds.filter(item => item.iid !== row.iid);
          } else {
            // 未映射，允许选择
            this.selectedInds = selection;
          }
        }).catch(error => {
          console.error('检查指标映射状态失败:', error);
          this.selectedInds = selection;
        });
      } else {
        // 非数字类型，直接更新选择
        this.selectedInds = selection;
      }
    },
    
    // 更新表格行类样式，添加已映射标记
    demandRowClassName({row}) {
      return row.isMapped ? 'mapped-row' : '';
    },
    
    indicatorRowClassName({row}) {
      return row.isMapped ? 'mapped-row' : '';
    },
    
    // 更新选择前检查
    selectable(row) {
      // 如果是数字类型且已映射，则不可选
      if (row.type === 'num' && row.isMapped) {
        return false;
      }
      return true;
    },

    // 添加检查括号是否平衡的辅助方法
    checkBracketBalance(formula) {
      const stack = [];
      const brackets = {
        '(': ')',
        '[': ']',
        '{': '}'
      };
      
      for (let i = 0; i < formula.length; i++) {
        const char = formula[i];
        if (char === '(' || char === '[' || char === '{') {
          stack.push(char);
        } else if (char === ')' || char === ']' || char === '}') {
          const last = stack.pop();
          if (!last || brackets[last] !== char) {
            return false;
          }
        }
      }
      
      return stack.length === 0;
    }
  }
};
</script>

<style lang="scss" scoped>
/* 整体样式优化 */
.app-container {
  background-color: #f5f7fa;
}

/* 面板容器样式 - 使用与struct一致的样式 */
.panel-container {
  background-color: #ffffff;
  border-radius: 4px;
  box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);
  height: calc(100vh - 140px);
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
  border: 1px solid #e8eaec;

  &:hover {
    box-shadow: 0 3px 12px 0 rgba(0, 0, 0, 0.08);
  }
}

/* 面板头部样式 - 使用与struct一致的样式 */
.panel-header {
  padding: 16px 20px;
  font-size: 16px;
  font-weight: 600;
  color: #17233d;
  background-color: #f8f8fc;
  border-bottom: 1px solid #e8eaec;
  display: flex;
  align-items: center;

  &::before {
    content: "";
    display: inline-block;
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background-color: #2d8cf0;
    margin-right: 12px;
  }
}

/* 搜索框样式 - 使用与struct一致的样式 */
.search-box {
  padding: 12px 16px;
  background-color: #fcfcfc;
  border-bottom: 1px solid #f0f0f0;

  .el-input {
    ::v-deep .el-input__inner {
      border-radius: 4px;
      border-color: #e0e0e0;

      &:hover, &:focus {
        border-color: #2d8cf0;
      }
    }

    ::v-deep .el-input__prefix {
      color: #808695;
    }
  }
}

/* 面板主体样式 - 使用与struct一致的样式 */
.panel-body {
  flex: 1;
  overflow: hidden;
  padding: 0;
  position: relative;
}

/* 树状结构样式 - 使用与struct一致的样式 */
::v-deep .el-tree {
  background-color: transparent;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  height: 100%;
  overflow: auto;

  /* 高亮选中的节点 */
  .el-tree-node.is-current > .el-tree-node__content {
    background-color: #ecf5ff;
    color: #409EFF;
  }

  /* 树节点样式 */
  .el-tree-node__content {
    height: 36px;
    border-radius: 3px;
    margin-bottom: 2px;
    transition: all 0.2s;

    &:hover {
      background-color: #f5f7fa;
    }
  }

  /* 缩进样式 */
  .el-tree-node__expand-icon {
    padding: 6px;
    color: #909399;
    transition: transform 0.3s;

    &.expanded {
      transform: rotate(90deg);
    }
  }

  /* 缩进样式 */
  .el-tree__indent {
    padding-left: 16px !important;
  }
}

/* 树节点样式 */
.tree-node-name {
  display: inline-flex !important;
  align-items: center;
  vertical-align: middle;

  .node-icon {
    margin-right: 8px;
    font-size: 16px;

    /* 文件夹图标 - 黄色 */
    &.el-icon-folder {
      color: #E6A23C;
    }

    /* 文档图标 - 蓝色 */
    &.el-icon-document {
      color: #409EFF;
    }
  }
}

/* 映射按钮区域 */
.mapping-actions {
  margin-top: 16px;
  display: flex;
  justify-content: center;

  .mapping-btn {
    min-width: 140px;
    height: 38px;
    font-weight: 500;
    letter-spacing: 1px;
    transition: all 0.3s ease;
    background-color: #2d8cf0;
    border-color: #2d8cf0;

    &:hover:not([disabled]) {
      background-color: #57a3f3;
      border-color: #57a3f3;
      box-shadow: 0 4px 12px rgba(45, 140, 240, 0.2);
      transform: translateY(-1px);
    }

    &[disabled] {
      background-color: #f7f7f7;
      border-color: #dcdee2;
      color: #c5c8ce;
    }
  }
}

/* 值显示区域 */
.value-wrapper {
  background-color: #f8f8fc;
  border: 1px solid #eaeaea;
  border-radius: 3px;
  padding: 4px 8px;
  transition: all 0.2s ease;
  min-height: 22px;

  &:hover {
    background-color: #eef2fb;
    border-color: #d9e1f2;
  }

  .text-value {
    color: #515a6e;
    font-size: 13px;
    word-break: break-all;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }

  .count-value {
    display: flex;
    align-items: center;
    color: #515a6e;
    font-size: 13px;

    i {
      margin-right: 4px;
      color: #808695;
    }
  }

  .empty-value {
    color: #c5c8ce;
  }
}

/* 映射对话框样式优化 */
.mapping-dialog {
  ::v-deep .el-dialog {
    border-radius: 6px;
    overflow: hidden;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }

  ::v-deep .el-dialog__header {
    padding: 20px 24px;
    border-bottom: 1px solid #e8eaec;
    background-color: #f8f8fc;
  }

  ::v-deep .el-dialog__title {
    font-size: 18px;
    font-weight: 600;
    color: #17233d;
    position: relative;
    padding-left: 12px;

    &::before {
      content: "";
      position: absolute;
      left: 0;
      top: 4px;
      bottom: 4px;
      width: 4px;
      background-color: #2d8cf0;
      border-radius: 2px;
    }
  }

  ::v-deep .el-dialog__body {
    padding: 24px;
  }

  ::v-deep .el-dialog__footer {
    padding: 16px 24px;
    border-top: 1px solid #e8eaec;
    background-color: #fcfcfc;
  }

  ::v-deep .el-button {
    min-width: 88px;
    transition: all 0.3s ease;

    &--primary {
      background-color: #2d8cf0;
      border-color: #2d8cf0;

      &:hover {
        background-color: #57a3f3;
        border-color: #57a3f3;
        box-shadow: 0 4px 12px rgba(45, 140, 240, 0.2);
        transform: translateY(-1px);
      }
    }
  }
}

.mapping-dialog-content {
  max-height: calc(80vh - 200px);
  overflow-y: auto;
}

.mapping-header {
  display: flex;
  align-items: center;
  margin-bottom: 24px;
  padding: 14px 20px;
  background-color: #f8f8fc;
  border-radius: 4px;
  border-left: 4px solid #2d8cf0;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);

  .dialog-icon {
    font-size: 24px;
    color: #2d8cf0;
    margin-right: 16px;
  }

  .mapping-subtitle {
    color: #515a6e;
    font-size: 14px;
    line-height: 1.6;
  }
}

/* 直接映射样式 */
.direct-mapping-section {
  height: 100%;
  box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);
  border: 1px solid #e8eaec;
  border-radius: 4px;
  transition: all 0.3s ease;

  &:hover {
    box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.08);
  }
}

.section-title {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  background-color: #f8f8fc;
  border-bottom: 1px solid #e8eaec;
  font-weight: 600;
  color: #17233d;
  border-radius: 4px 4px 0 0;

  i {
    font-size: 16px;
    margin-right: 8px;
    color: #2d8cf0;
  }

  .count-tag {
    margin-left: 8px;
  }
}

.option-section-title {
  .source-tag {
    margin-left: auto;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.section-content {
  padding: 12px;
  background-color: white;
  border-radius: 0 0 4px 4px;
}

.mapping-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mapping-item {
  display: flex;
  align-items: center;
}

.mapping-tag {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 8px 12px;
  margin: 0;

  i {
    margin-right: 8px;
  }

  .item-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .type-tag {
    margin-left: 8px;
  }
}

/* 映射总结 */
.mapping-summary {
  margin-top: 24px;
  border: 1px solid #e8eaec;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);

  .summary-title {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    background-color: #f8f8fc;
    border-bottom: 1px solid #e8eaec;
    font-weight: 600;
    color: #17233d;

    i {
      color: #2d8cf0;
      margin-right: 8px;
    }
  }

  .summary-content {
    padding: 20px;

    p {
      margin: 0 0 16px 0;
      color: #515a6e;
      font-size: 14px;
    }
  }
}

.mapping-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background-color: #f8fafc;
  border-radius: 4px;
  border: 1px dashed #d7dce6;

  .mapping-preview-left, .mapping-preview-right {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 16px 30px;
    background-color: white;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    min-width: 120px;
    transition: transform 0.3s ease;

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }
  }

  .mapping-preview-left {
    border-top: 3px solid #2d8cf0;

    .preview-demand-count {
      font-size: 28px;
      font-weight: 600;
      color: #2d8cf0;
      margin-bottom: 8px;
    }
  }

  .mapping-preview-right {
    border-top: 3px solid #19be6b;

    .preview-ind-count {
      font-size: 28px;
      font-weight: 600;
      color: #19be6b;
      margin-bottom: 8px;
    }
  }

  .preview-text {
    color: #808695;
    font-size: 14px;
  }

  .mapping-preview-arrow {
    margin: 0 24px;

    i {
      font-size: 24px;
      color: #808695;
      background-color: #f0f4f9;
      border-radius: 50%;
      padding: 8px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
    }
  }
}

/* 选项映射样式 */
.option-mapping-container {
  .mapping-instructions {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    padding: 12px 16px;
    background-color: #f0f6ff;
    border-radius: 4px;

    .instruction-icon {
      font-size: 18px;
      color: #2d8cf0;
      margin-right: 10px;
    }

    span {
      color: #515a6e;
      line-height: 1.6;
    }
  }
}

.option-mapping-row {
  margin-bottom: 24px;
}

.option-table {
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #e8eaec;

  ::v-deep .el-table__row.current-row {
    background-color: #eef6ff !important;

    td {
      background-color: #eef6ff !important;
      border-bottom: 1px solid #d7e4f6 !important;
    }
  }

  ::v-deep th {
    background-color: #f8f8fc !important;
  }
}

.option-cell {
  display: flex;
  align-items: center;

  .option-value {
    flex: 1;
    color: #515a6e;
  }

  .mapped-badge {
    background-color: #ed4014;
    color: white;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 12px;
    margin-left: 8px;
  }
}

.mapping-action-col {
  display: flex;
  justify-content: center;
}

.mapping-action-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 0 12px;
}

.selected-option-container {
  margin-bottom: 20px;
  width: 100%;
}

.selected-option-display {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.selected-option {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 12px;
  margin-bottom: 12px;
  border: 1px dashed #d7dce6;
  border-radius: 4px;
  background-color: #f8f8fc;
  min-height: 48px;
  transition: all 0.3s ease;

  .option-icon {
    margin-right: 8px;
    color: #808695;
  }

  .placeholder {
    color: #c5c8ce;
    font-style: italic;
  }

  &.has-selection {
    border-style: solid;
    background-color: white;
  }

  &.selected-demand-option.has-selection {
    border-color: #2d8cf0;
    box-shadow: 0 2px 8px rgba(45, 140, 240, 0.15);

    .option-icon {
      color: #2d8cf0;
    }
  }

  &.selected-indicator-option.has-selection {
    border-color: #19be6b;
    box-shadow: 0 2px 8px rgba(25, 190, 107, 0.15);

    .option-icon {
      color: #19be6b;
    }
  }
}

.map-direction {
  margin: 6px 0;
  color: #808695;

  i {
    font-size: 20px;
    background-color: #f0f4f9;
    border-radius: 50%;
    padding: 6px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
  }
}

.add-mapping-btn {
  width: 100%;
  margin-top: 12px;
  height: 36px;
  transition: all 0.3s ease;

  &:not([disabled]):hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(45, 140, 240, 0.2);
  }
}

.mapping-list-container {
  margin-top: 28px;
  border: 1px solid #e8eaec;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
}

.mapping-list-title {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  background-color: #f8f8fc;
  border-bottom: 1px solid #e8eaec;
  font-weight: 600;
  color: #17233d;

  i {
    margin-right: 8px;
    color: #2d8cf0;
  }

  .count-tag {
    margin-left: 8px;
  }
}

.mappings-table {
  ::v-deep .el-button--text {
    padding: 0;
  }

  .delete-btn {
    color: #ed4014;
    font-size: 16px;
    transition: all 0.2s ease;

    &:hover {
      transform: scale(1.1);
      opacity: 0.8;
    }
  }
}

.mapping-item-cell {
  display: flex;
  align-items: center;

  .cell-icon {
    margin-right: 8px;
  }

  .demand-icon {
    color: #2d8cf0;
  }

  .indicator-icon {
    color: #19be6b;
  }
}

/* 类型不匹配提示样式 */
.type-mismatch-tooltip {
  max-width: 300px;
  line-height: 1.5;
}

.checkbox-wrapper {
  display: inline-block;
}

/* 被禁用的行样式 */
::v-deep .el-table__row.disabled-row {
  background-color: #f9f9f9;

  td {
    color: #c5c8ce !important;
  }

  &:hover td {
    background-color: #f9f9f9 !important;
  }
}

/* 已映射行样式 */
::v-deep .el-table__row.mapped-row {
  background-color: #f3f8ed;

  &:hover > td {
    background-color: #eaf3e2 !important;
  }

  td {
    color: #19be6b !important;
  }
}

/* 响应式适配 */
.splitpanes.default-theme .splitpanes__pane {
  background-color: #f5f7fa;
}

.splitpanes.default-theme .splitpanes__splitter {
  background-color: #e8eaec;
  position: relative;

  &:hover {
    background-color: #dcdee2;
  }

  &:before, &:after {
    background-color: #2d8cf0;
  }
}

/* 自定义滚动条 */
::v-deep {
  ::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  ::-webkit-scrollbar-track {
    background: #f5f7fa;
    border-radius: 4px;
  }

  ::-webkit-scrollbar-thumb {
    background: #dcdee2;
    border-radius: 4px;

    &:hover {
      background: #c5c8ce;
    }
  }
}

/* 已有映射关系部分样式 */
.existing-mappings-section {
  margin-top: 24px;
  border-top: 1px dashed #e8eaec;
  padding-top: 16px;
}

.existing-mappings-section .section-title {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  font-size: 15px;
  font-weight: 600;
  color: #17233d;
}

.existing-mappings-section .section-title i {
  color: #2d8cf0;
  margin-right: 8px;
  font-size: 16px;
}

.existing-mappings-section .count-tag {
  margin-left: 8px;
}

.existing-mappings-section .delete-btn {
  color: #ed4014;
  font-size: 16px;
  transition: all 0.2s ease;
}

.existing-mappings-section .delete-btn:hover {
  transform: scale(1.1);
  opacity: 0.8;
}

// Add these styles to your component
.mapping-section {
  margin-top: 20px;
  margin-bottom: 20px;
  border: 1px solid #ebeef5;
  padding: 15px;
  border-radius: 4px;
  background-color: #f9fafc;
}

.mapping-section h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #303133;
  font-size: 16px;
  font-weight: 500;
}

.mapping-table {
  margin-bottom: 10px;
}

.mapping-arrow {
  font-size: 20px;
  color: #409EFF;
}

.option-source {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.no-mappings-info {
  display: flex;
  align-items: center;
  padding: 10px 15px;
  background-color: #f4f6f8;
  border-radius: 4px;
  margin: 15px 0;
  color: #909399;
}

.no-mappings-info i {
  margin-right: 8px;
  font-size: 16px;
}

.mapping-results-section {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fafafa;
}

.section-title {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.count-badge {
  display: inline-block;
  background-color: #409EFF;
  color: white;
  border-radius: 10px;
  padding: 2px 8px;
  font-size: 12px;
  margin-left: 8px;
}

.debug-info {
  margin-top: 15px;
  padding: 10px;
  background-color: #f0f9eb;
  border: 1px dashed #e1f3d8;
  border-radius: 4px;
  font-family: monospace;
  font-size: 12px;
  max-height: 200px;
  overflow: auto;
}

.existing-mappings-container {
  margin-top: 20px;
  padding: 20px;
  border: 1px solid #E4E7ED;
  border-radius: 8px;
  background-color: #FFFFFF;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid #EBEEF5;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  letter-spacing: 0.5px;
}

.option-value-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 15px;
  border-radius: 6px;
  text-align: center;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  border: 1px solid transparent;
}

.option-text {
  font-size: 14px;
  line-height: 1.5;
  word-break: break-all;
  font-weight: 500;
  letter-spacing: 0.3px;
}

.demand-option {
  background: linear-gradient(to bottom, #e6f2ff 0%, #d6e9ff 100%);
  color: #1875f0;
  border-color: #c0d9ff;
  position: relative;
}

.demand-option::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: url('');
  opacity: 0.4;
  border-radius: inherit;
  pointer-events: none;
}

.indicator-option {
  background: linear-gradient(to bottom, #f0f9eb 0%, #e1f3d8 100%);
  color: #529b2e;
  border-color: #d1edc4;
  position: relative;
}

.indicator-option::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: url('');
  opacity: 0.4;
  border-radius: inherit;
  pointer-events: none;
}

.option-value-cell:hover {
  transform: translateY(-1px);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.1);
}

.mapping-arrow-container {
  position: relative;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mapping-line {
  position: absolute;
  width: 70%;
  height: 2px;
  background: linear-gradient(to right, #c0d9ff, #d1edc4);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.mapping-arrow-wrapper {
  position: relative;
  background: linear-gradient(135deg, #4db3ff 0%, #2e90e5 100%);
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  transition: all 0.3s ease;
  box-shadow: 0 2px 6px rgba(45, 140, 240, 0.4);
}

.mapping-arrow-wrapper:hover {
  transform: scale(1.1);
  box-shadow: 0 4px 8px rgba(45, 140, 240, 0.5);
}

.mapping-arrow-icon {
  color: white;
  font-size: 14px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.delete-btn {
  color: #F56C6C;
  font-size: 13px;
  transition: all 0.3s;
  padding: 5px 8px;
  border-radius: 4px;
}

.delete-btn:hover {
  color: #F56C6C;
  background-color: #fef0f0;
  text-decoration: underline;
}

/* 增强表格美观度 */
.existing-mappings-table ::v-deep .el-table {
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.existing-mappings-table ::v-deep .el-table__header-wrapper th {
  background: linear-gradient(to bottom, #fafbfc 0%, #f4f6f8 100%);
  color: #606266;
  font-weight: 600;
  padding: 12px 0;
  height: 50px;
  border-bottom: 2px solid #EBEEF5;
}

.existing-mappings-table ::v-deep .el-table__row td {
  padding: 16px 0;
  transition: background-color 0.3s;
}

.existing-mappings-table ::v-deep .el-table__row:hover {
  background-color: #fafafa;
}

/* 为映射箭头添加动画效果 */
@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.1); }
  100% { transform: scale(1); }
}

.existing-mappings-table:hover .mapping-arrow-wrapper {
  animation: pulse 1.5s infinite ease-in-out;
}

/* 已映射选项行样式 */
.mapped-option-row {
  background-color: #f0f0f0 !important;
  opacity: 0.8;
  cursor: not-allowed !important;
  position: relative;
}

.mapped-option-row td {
  position: relative;
}

.mapped-option-row td::after {
  content: "已映射";
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  background-color: #909399;
  color: white;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

/* 确保表格行内的内容不被覆盖 */
.el-table__row td {
  position: relative;
}

.function-mapping-toolbar {
  margin-bottom: 15px;
  text-align: right;
}

.formula-tips {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.mb-2 {
  margin-bottom: 8px;
}

.mt-2 {
  margin-top: 8px;
}

.mt-3 {
  margin-top: 12px;
}

.text-muted {
  color: #909399;
}

.mapped-row {
  background-color: #f0f9eb !important;
}

.mapped-row td {
  color: #67c23a;
}

.mapped-row:hover > td {
  background-color: #e7f6df !important;
}

.mapping-button-group {
  margin-bottom: 15px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 智能映射按钮 */
.mapping-btn {
  min-width: 140px;
  height: 38px;
  font-weight: 500;
  letter-spacing: 1px;
  transition: all 0.3s ease;
  background-color: #2d8cf0;
  border-color: #2d8cf0;
  margin-top: 15px;
  position: relative;
  
  &::after {
    content: attr(data-type);
    position: absolute;
    bottom: -22px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
    color: #909399;
    white-space: nowrap;
    padding: 2px 6px;
    background-color: #f5f7fa;
    border-radius: 3px;
    opacity: 0;
    transition: opacity 0.3s;
  }
  
  &:hover::after {
    opacity: 1;
  }

  &:hover:not([disabled]) {
    background-color: #57a3f3;
    border-color: #57a3f3;
    box-shadow: 0 4px 12px rgba(45, 140, 240, 0.2);
    transform: translateY(-1px);
  }

  &[disabled] {
    background-color: #f7f7f7;
    border-color: #dcdee2;
    color: #c5c8ce;
  }
}

/* 函数映射对话框样式 */
.function-mapping-dialog {
  ::v-deep .el-dialog {
    border-radius: 6px;
    overflow: hidden;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }

  ::v-deep .el-dialog__header {
    padding: 20px 24px;
    border-bottom: 1px solid #e8eaec;
    background-color: #f8f8fc;
  }

  ::v-deep .el-dialog__title {
    font-size: 18px;
    font-weight: 600;
    color: #17233d;
    position: relative;
    padding-left: 12px;

    &::before {
      content: "";
      position: absolute;
      left: 0;
      top: 4px;
      bottom: 4px;
      width: 4px;
      background-color: #2d8cf0;
      border-radius: 2px;
    }
  }

  ::v-deep .el-dialog__body {
    padding: 24px;
  }

  ::v-deep .el-dialog__footer {
    padding: 16px 24px;
    border-top: 1px solid #e8eaec;
    background-color: #fcfcfc;
  }
}

/* 添加已映射行的样式 */
::v-deep .el-table .mapped-row {
  background-color: #f0f9eb;
  color: #67c23a;
}

::v-deep .el-table .mapped-row:hover > td {
  background-color: #e1f3d8 !important;
}

/* 添加映射标记样式 */
.mapping-status {
  display: inline-block;
  padding: 2px 6px;
  font-size: 12px;
  border-radius: 3px;
  margin-left: 5px;
}

.status-mapped {
  background-color: #f0f9eb;
  color: #67c23a;
  border: 1px solid #c2e7b0;
}
</style>

<!-- Global styles for the tooltips -->
<style>
.mapped-tooltip {
  border: 1px solid #fbc4c4 !important;
  background-color: #fff0f0 !important;
  color: #f56c6c !important;
  font-weight: bold !important;
}

.mapped-tooltip .popper__arrow {
  border-bottom-color: #fbc4c4 !important;
}

.mapped-tooltip .popper__arrow::after {
  border-bottom-color: #fff0f0 !important;
}
</style>
